﻿

namespace Mulala.Cavan.Application.MainBoundedContext.CacheModule
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using AopAlliance.Intercept;
    using Mulala.Cavan.Domain.MainBoundedContext.SearchModule;
    using Mulala.Cavan.Core.Memcache;
    using Mulala.Cavan.Core.Extension;

    public class TagCacheAdvice : IMethodInterceptor
    {
        private bool _cached = false;

        public object Invoke(IMethodInvocation invocation)
        {
            object returnValue = null;
            CacheAttribute[] cacheInfo =
                (CacheAttribute[])invocation.Method.GetCustomAttributes(typeof(CacheAttribute), false);
            if (cacheInfo.Length > 0)
            {
                this._cached = cacheInfo[0].Cached;
            }
            if (this._cached)
            {
                TagSearch search = (TagSearch)invocation.Arguments.FirstOrDefault(a => a.GetType() == typeof(TagSearch));
                StringBuilder sbKey = new StringBuilder();
                sbKey.Append(cacheInfo[0].Key);
                if (search.IsNotNull())
                {
                    if (search.GroupType.GetHashCode() > 0)
                    {
                        sbKey.Append("_bygrouptype_");
                        sbKey.Append(search.GroupType.GetHashCode().ToString());
                    }
                }
                else
                {
                    object id = invocation.Arguments.FirstOrDefault(a => a.GetType() == typeof(int));
                    if ((id is int) && (int)id > 0)
                    {
                        sbKey.Append("_byid_");
                        sbKey.Append(id.ToString());
                    }
                }

                returnValue = MemcachedHelper.Get(sbKey.ToString());
                if (returnValue == null)
                {
                    returnValue = invocation.Proceed();
                    MemcachedHelper.Store(sbKey.ToString(), returnValue);
                }
            }
            else
            {
                returnValue = invocation.Proceed();
            }
            return returnValue;
        }
    }
}
